import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

//引入plugins中的插件src/views/visualization/plugins
import CameraControlPlugin from '@/views/visualization/plugins/CameraControlPlugin'
import CameraPlugin from '@/views/visualization/plugins/CameraPlugin'
import { DirectionalLight } from '@/views/visualization/plugins/LightPlugin'
import bg from '@/views/visualization/plugins/BackgroundPlugin' 

// 引入模型捕获
import { GetIntersects } from '@/views/visualization/plugins/MouseClickPlugin'

export default {
  data() {
    return {
      // dom节点（容器）
      container: undefined,
      containerHeight: undefined,
      containerWidth: undefined,
      // 场景
      scene: undefined,
      // 相机
      camera: undefined,
      // 渲染器
      renderer: undefined,
      // 相机控制对象
      cameraControl: undefined,
      //模型加载器
      GLTFLoader: undefined,
      // 场景鼠标坐标
      mouse: new THREE.Vector2(),
      // 全局鼠标坐标
      globalMouse: {
        x: undefined,
        y: undefined
      }
    }
  },

  methods: {
    /**
     * 场景初始化（容器、相机、光源、场景）
     */ 
    initScene(){
      /**
       * 容器
       */ 
      this.container = document.querySelector('#container')
      this.containerHeight = container.offsetHeight
      this.containerWidth = container.offsetWidth

      /**
       * 场景
       */
      this.scene = new THREE.Scene()
      // 场景添加灰色背景
      // this.scene.background = new THREE.Color(0xa0a0a0)
      // this.scene.background = bg


      /** 
       * 相机、相机位置
       */ 
      this.camera = CameraPlugin(new THREE.PerspectiveCamera(75,this.containerWidth/this.containerHeight,0.1,1000))

      /** 
       * 灯光
       */ 
      this.scene.add(new THREE.AmbientLight(0x222222))//添加一个全局环境光
      this.scene.add(DirectionalLight) //添加平行光到场景

      /** 
       * 渲染器
       */ 
      this.renderer = new THREE.WebGLRenderer({
        //增加下面属性，打开抗锯齿
        antialias:true,
        // 设置renderer不覆盖背景
        alpha:true
      })
      this.renderer.setSize( this.containerWidth, this.containerHeight )
      this.renderer.shadowMap.enabled = true// 开启渲染阴影效果
      this.renderer.gammaOutput = true// 模型材质正常显示
      this.renderer.gammaFactor = 2.2
      this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
      this.container.appendChild( this.renderer.domElement )
      
      /**
       * 背景处理
       */
      bg(this.scene,this.renderer)

      /**
       * 注册鼠标移动事件
       */
      this.container.addEventListener("mousemove", this.onDocumentMouseMove, false)
    
      /**
       * 注册双击事件监听
       */
      this.container.addEventListener("dblclick", this.onDblClick, false)
    },

    /**
     * 工具初始化 （相机控制、模型加载器）
     */ 
    initUtils(){
      this.cameraControl = CameraControlPlugin(new OrbitControls(this.camera, this.renderer.domElement))
      // 模型加载器
      this.GLTFLoader = new GLTFLoader()
    },

    /**
     * 窗口适配（设置窗口事件监听）
     */ 
    windowAdaptation(){
      // onresize是window触发的 所以需要保存一份this
      let _this = this
      // 窗口适配
      window.onresize=function (){
        // 重新设置渲染器尺寸
        _this.renderer.setSize( _this.container.offsetWidth, _this.container.offsetHeight )
        // 重新设置相机长宽度比
        _this.camera.aspect=_this.container.offsetWidth/_this.container.offsetHeight
        // 刷新（矩阵）
        _this.camera.updateProjectionMatrix()
      }
      // 通过插件处理div变化刷新renderer的大小
      var elementResizeDetectorMaker = require("element-resize-detector")
      var erd = elementResizeDetectorMaker()
      erd.listenTo(this.container,function(element){
        _this.containerWidth = element.offsetWidth
        _this.containerHeight = element.offsetHeight
        console.log("Size: " +  _this.containerWidth + "x" +  _this.containerHeight)
        _this.renderer.setSize(_this.containerWidth,_this.containerHeight)
      })
    },

    /**
     * 鼠标捕获
     */
    onDocumentMouseMove( event ) 
    {
      // 获取dom元素到窗口左上角的偏移量
      var left = this.container.getBoundingClientRect().left
      var top = this.container.getBoundingClientRect().top
      // update the mouse variable
      this.mouse.x = ((event.clientX - left) / this.containerWidth) * 2 - 1
      this.mouse.y = -((event.clientY - top) / this.containerHeight) * 2 + 1
      this.globalMouse.x = event.clientX - left
      this.globalMouse.y = event.clientY - top
    },

    /**
     * 双击事件处理
     */
    onDblClick(event){
      var intersects = GetIntersects(event,this)
      this.handleDblClick(intersects)
    },
    

    /**
     * 鼠标悬浮拾取(得到悬浮在什么mesh上)
     */
    getHoverMesh(){
      var raycaster = new THREE.Raycaster()
      raycaster.setFromCamera(this.mouse, this.camera)
      var intersects = raycaster.intersectObjects(this.scene.children, true)
      if(intersects[0]){
        this.handleHover(intersects[0])
      }
    },

    /** 
     * 循环渲染
     */ 
    animate(){
      requestAnimationFrame( this.animate )
        // 交互代码
        
        // 更新相机的位
        this.cameraControl.update()
        //设置渲染函数
        this.renderer.render( this.scene, this.camera )
        this.getHoverMesh()
    },

  },

  mounted() {
    // 场景初始化（容器、相机、光源、场景、渲染器）
    this.initScene()
    // 工具初始化 （相机控制、模型加载器）
    this.initUtils()
    // 窗口适配
    this.windowAdaptation()
    // animate 循环渲染
    this.animate()
  },
}